#include<sys/socket.h>;
#include<string.h>;
#include<netinet/in.h>;
#include<stdio.h>;
#include<stdlib.h>;
#include<fcntl.h>;
#include<sys/stat.h>;
#include<unistd.h>;
#include<errno.h>;
#include<sys/select.h>;
#include<sys/time.h>;
#include<unistd.h>;
#include<sys/types.h>;

#define SERV_PORT 2800
#define MAX_SIZE 1024*50

void recvUDP(char name[20],int sockfd)
{

        int ret,fd;
        mode_t fdmode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
        char mesg[MAX_SIZE];
        fd_set rdset;
        int rlen,wlen;
        int i;
		
		struct timeval start,end;
		double timeuse;
		double usetime;
		double rcv=0;
		double speed=0;
		gettimeofday (&start , NULL);		

        fd = open(name,O_RDWR|O_CREAT|O_APPEND,fdmode);
        if(fd == -1)
        {
                printf("open file %s error:%n",name,strerror(errno));
                exit(-1);
        }

        for(i=1;;i++)
        {
                FD_ZERO(&rdset);
                FD_SET(sockfd,&rdset);

                ret = select(sockfd+1,&rdset,NULL,NULL,NULL);
                if(ret == -1)
                {
                        printf("select error %s\n",strerror(errno));
                        exit(-1);
                }
                                
                if(FD_ISSET(sockfd,&rdset))
                {
                        memset(mesg,0,MAX_SIZE);
                        rlen = read(sockfd,mesg,MAX_SIZE);
                        if(rlen <=0 )
                        {
                                printf("read error %s\n",strerror(errno));
                                exit(-1);
                        }
                        
                        if(!strcmp(mesg,"end"))
                        {
                                printf("recv end.\n");
								printf("=================================\n");
									printf("tv_sec: %d\n", start.tv_sec);
									printf( "tv_usec: %d\n",start.tv_usec);
									printf("=================================\n");
									gettimeofday (&end , NULL);
									printf("2 tv_sec: %d\n", end.tv_sec);
									printf( "2 tv_usec: %d\n",end.tv_usec);
									printf("---------------------------------\n");
									rcv = MAX_SIZE*(i-1);
									timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec;
										
									speed = ((double)rcv/timeuse)*(double)1000000;
									printf("us---package rcv: %d \n", i-1);
									printf("us---data rcv: %f b\n", rcv);
									printf("us---time used: %f us\n", timeuse);
									printf("us---speed: %f b/s\n", speed);
									printf("us---speed: %f KB/s\n", speed/(8*1024));
									printf("us---speed: %f Mb/s\n", speed/(double)(1024*1024));                                
								break;
                        }

                        wlen = write(fd,mesg,rlen);
                        if(wlen != rlen )
                        {
                                printf("write error %s\n",strerror(errno));
                                exit(-1);
                        }        
                }
                
                printf("The %d times write\n",i);
        }

        close(fd);
}

int main(int argc, char *argv[])
{
        int sockfd;
        int r;
        struct sockaddr_in servaddr;

        sockfd = socket(AF_INET,SOCK_DGRAM,0);

        bzero(&servaddr,sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(SERV_PORT);

        if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) == -1)
        {
                perror("bind error");
                exit(-1);
        }
        
        recvUDP(argv[1],sockfd);

        return 0;

}